package com.gjzhao.fmmall.config;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Description: Gateway全局过滤器配置 - 拦截所有访问网关服务的请求
 * @Author: gjzhao
 * @Date Created in 2022-02-16 10:08 下午
 */
@Component //注入spring
public class GatewayGlobalFilterConfig implements GlobalFilter, Ordered { // 需要实现gateway提供的 GlobalFilter 注解，同时实现 Ordered 定义执行顺序

    private Logger logger = LoggerFactory.getLogger(getClass());

    //过滤逻辑:
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("-----进入过滤器，校验token---");

        //获取请求头中key为token的值
        List<String> list = exchange.getRequest().getHeaders().get("token");
        if (list != null && list.size() > 0) {
            String token = list.get(0);
            // todo 根据当前token值去redis中进行查询，若存在值，则表示token校验成功，否则校验失败
            logger.info("-----token值:{}-----", token);
            return chain.filter(exchange);
        } else {
            logger.info("-----当前请求的请求头中不存在token----");
            //如果没有token，或者token过期
            ServerHttpResponse response = exchange.getResponse();
            //设置响应头
            response.getHeaders().add("Content-Type", "application/json;charset=utf-8");
            //设置状态码
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            // 封装响应数据
            String str = "token不存在";
            DataBuffer dataBuffer = response.bufferFactory().wrap(str.getBytes());
            return response.writeWith(Mono.just(dataBuffer));
        }
    }

    // 定义执行顺序
    @Override
    public int getOrder() {
        return 0;
    }
}
